/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.acme.jpa.idempotent.repository;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import jakarta.inject.Named;
import jakarta.persistence.EntityManagerFactory;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.jpa.TransactionStrategy;
import org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository;
import org.eclipse.microprofile.config.inject.ConfigProperty;

@ApplicationScoped
public class JpaIdempotentRoute extends RouteBuilder {

    /**
     * Gets the HTTP port where the example harness is listening for API calls.
     */
    @ConfigProperty(name = "quarkus.http.port", defaultValue = "8085")
    private int quarkusPlatformHttpPort;

    /**
     * The camel route expect a bean named jpaIdempotentRepository of type IdempotentRepository to be present in the
     * registry. One way to create such a bean is to use a producer method as shown below.
     */
    @Produces
    @Named
    JpaMessageIdRepository jpaIdempotentRepository(EntityManagerFactory entityManagerFactory,
            TransactionStrategy transactionStrategy) {
        /**
         * The JPA message id repository will store duplicate message IDs in a database. Distinct repository could be
         * created on the same database by using different processor names.
         */
        return new JpaMessageIdRepository(entityManagerFactory, transactionStrategy, "myProcessorName");
    }

    @Override
    public void configure() {
        /**
         * Read the files generated by the example harness in the target/input-files folder
         */
        from("file:target/input-files")
                .log("Received an example input file having the content ${body}")
                /**
                 * The idempotent consumer pattern could be used as below. All messages presented with the same body more
                 * than once will be filtered out.
                 */
                .idempotentConsumer(simple("${body}"))
                /**
                 * A place is needed in order to keep track of duplicate message bodies, it's called an idempotent
                 * repository The idempotent repository could be provided as a bean from the registry like below.
                 */
                .idempotentRepository("jpaIdempotentRepository")
                .log("The file was not a duplicate, invoke the costly API")
                /**
                 * Sends the content of the file to the costly API simulated by the example harness.
                 */
                .toF("http://localhost:%s/costly-api-call", quarkusPlatformHttpPort);
    }
}
